package com.leenmvc.core.security.service.core;

import com.leenmvc.core.base.BaseService;
import com.leenmvc.core.dao.mysql.wrapper.QueryWrapper;
import com.leenmvc.core.security.entity.core.SysApi;
import com.leenmvc.core.security.entity.core.SysApiParam;
import com.leenmvc.core.security.entity.core.SysApiResult;
import org.apache.ibatis.annotations.Mapper;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;


@Service
@Mapper
public class SysApiService extends BaseService<SysApi> {

    @Autowired
    private SysApiParamService sysApiParamService;

    @Autowired
    private SysApiResultService sysApiResultService;

    @Autowired
    private SysPermissionService sysPermissionService;

//    @Autowired
//    private SysApiService sysApiService;
//
//    @Autowired
//    private SysPermission syspi;

    @Override
    public int deleteByIds(Object[] ids) {
        int sum = 0;
        int byIds = super.deleteByIds(ids);
        sum += byIds;
        for (int i = 0; i < ids.length; i++) {
            int delete = sysApiParamService.delete("apiId", ids[i]);
            sum += delete;
        }
        return sum;
    }

    public StringBuilder exportHtml() {
        List<SysApi> allApis = getAll();
        StringBuilder html = new StringBuilder();
        html.append("<html>");
        html.append("<head>");
        html.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/>");
        html.append("</head>");
        html.append("<body style='text-align:center;'>");
        allApis.forEach(x -> {
            html.append("<h1 class='note'>");
            html.append(x.getOperation());
            html.append("</h1>");
            html.append("<table align='center' class='table'>");
            html.append("<tr>");
            html.append("<th>");
            html.append("简单说明");
            html.append("</th>");
            html.append("<td class='note' colspan='4'>");
            html.append(x.getOperation());
            html.append("</td>");
            html.append("</tr>");

            html.append("<tr>");
            html.append("<th>");
            html.append("类名称");
            html.append("</th>");
            html.append("<td class='className' colspan='4'>");
            html.append(x.getClassName());
            html.append("</td>");
            html.append("</tr>");

            html.append("<tr>");
            html.append("<th>");
            html.append("方法名");
            html.append("</th>");

            html.append("<td colspan='4'>");
            html.append(x.getMethodName());
            html.append("</td>");
            html.append("</tr>");

            html.append("<tr>");
            html.append("<th class='param' style='width:10%;' colspan='1'>");
            html.append("请求参数");
            html.append("</th>");

            html.append("<td class='param' style='width:30%;' colspan='1'>");
            html.append("参数名");
            html.append("</td>");

            html.append("<td class='param' style='width:10%;' colspan='1'>");
            html.append("数据类型");
            html.append("</td>");

            html.append("<td class='param' style='width:10%;' colspan='1'>");
            html.append("是否必填");
            html.append("</td>");

            html.append("<td class='param' style='width:40%;' colspan='1'>");
            html.append("说明");
            html.append("</td>");
            html.append("</tr>");
            List<SysApiParam> apiParams = sysApiParamService.getList("apiId", x.getId());
            //添加参数表格
            if (null != apiParams && apiParams.size() != 0) {
                //参数不为空且为实体
                if ("requestBody".equals(apiParams.get(0).getParamType())) {
                    int size = apiParams.size();
                    size = size + 1;
                    html.append("<tr>");
                    html.append("<th rowspan=' " + size + "'>");
                    html.append("实体名称");
                    html.append("</th>");
                    apiParams.forEach(y -> {
                        html.append("<tr>");
                        html.append("<td>");
                        html.append(y.getParamName());
                        html.append("</td>");
                        html.append("<td>");
                        html.append(y.getParamType());
                        html.append("</td>");
                        html.append("<td>");
                        html.append(y.getRequired());
                        html.append("</td>");
                        html.append("<td colspan='2'>");
                        html.append(y.getNote());
                        html.append("</td>");
                        html.append("</tr>");
                    });
                } else {
                    //有参数但是参数不为实体
                    apiParams.forEach(y -> {
                        html.append("<tr>");
                        html.append("<td>");
                        html.append("");
                        html.append("</td>");

                        html.append("<td>");
                        html.append(y.getParamName());
                        html.append("</td>");

                        html.append("<td>");
                        html.append(y.getParamType());
                        html.append("</td>");
                        html.append("<td>");
                        html.append(y.getRequired());
                        html.append("</td>");

                        html.append("<td colspan='2'>");
                        html.append(y.getNote());
                        html.append("</td>");
                        html.append("</tr>");
                    });
                }
            } else {
                //没参数
                html.append("<tr>");
                html.append("<th colspan = '5'>");
                html.append("无参数");
                html.append("</th>");
                html.append("</tr>");
            }
            html.append("<tr>");
            html.append("<th colspan='1'>");
            html.append("请求方式");
            html.append("</th>");

            html.append("<td colspan='4'>");
            html.append(x.getRequestMethod());
            html.append("</td>");
            html.append("</tr>");

            html.append("<tr>");
            html.append("<th colspan='1'>");
            html.append("路径");
            html.append("</th>");

            html.append("<td colspan='4'>");
            html.append(x.getUri());
            html.append("</td>");
            html.append("</tr>");

            html.append("<tr>");
            html.append("<th colspan='1'>");
            html.append("授权");
            html.append("</th>");

            html.append("<tr>");
            html.append("<th>");
            html.append("返回信息");
            html.append("</th>");
            html.append("<td class='note' colspan='1.5'>");
            html.append("返回类型");
            html.append("</td>");

            html.append("<td class='note' colspan='1.5'>");
            html.append("返回名称");
            html.append("</td>");

            html.append("<td class='note' colspan='2'>");
            html.append("返回说明");
            html.append("</td>");
            html.append("</tr>");

            QueryWrapper queryWrapper = getQueryWrapper(SysApiResult.class);
            List<SysApiResult> sysApiResults = sysApiResultService.query(queryWrapper.eq("apiId",x.getId()).orderBy("id","desc"));
            sysApiResults.forEach(r -> {
                html.append("<tr>");
                html.append("<td>");
                html.append("");
                html.append("</td>");

                html.append("<td>");
                html.append(r.getParamType());
                html.append("</td>");

                html.append("<td>");
                html.append(r.getParamName());
                html.append("</td>");

                html.append("<td colspan='2'>");
                html.append(r.getNote());
                html.append("</td>");
                html.append("</tr>");

            });
            html.append("</table>");
            html.append("<br>");
            html.append("<br>");
            html.append("<br>");
        });
        html.append("</body>");
        html.append("</html>");
        return html;
    }


    public XWPFDocument exportWord() {
        List<SysApi> allApis = getAll();
        //创建一个空白word
        XWPFDocument document = new XWPFDocument();
        int i = 0;
        for (SysApi api : allApis) {
            //创建一个表格  -->每一个接口一个表格
            XWPFTable table = document.createTable();

//            setTableStyle(table);
            table.setStyleID("tbl-text");
            setTableWidth(table,"9000");
//            CTTbl ctTbl = table.getCTTbl();
//            CTTblPr tblPr = ctTbl.getTblPr();
//            org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPPr tblpPr = tblPr.getTblpPr();
            //创建一行  --> 说明
            XWPFTableRow operation = table.getRow(0);
            operation.getCell(0).setText("接口说明");
            operation.addNewTableCell().setText(api.getOperation());
            operation.addNewTableCell().setText("2");
            operation.addNewTableCell().setText("3");
            operation.addNewTableCell().setText("4");
            operation.addNewTableCell().setText("5");
            operation.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            //创建第二行 --> URL
            XWPFTableRow url = table.createRow();
            url.getCell(0).setText("URL");
            url.getCell(1).setText(api.getUri());
            url.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            //创建第三行 --> 授权
            XWPFTableRow requiresPermissions = table.createRow();
            requiresPermissions.getCell(0).setText("授权");
            requiresPermissions.getCell(1).setText(api.getRequiresPermissions());
            requiresPermissions.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            //创建第四行 --> 请求方式
            XWPFTableRow requestType = table.createRow();
            requestType.getCell(0).setText("请求方式");
            requestType.getCell(1).setText(api.getRequestMethod());
            requestType.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            //创建第五行  -->版本
            XWPFTableRow version = table.createRow();
            version.getCell(0).setText("版本");
            version.getCell(1).setText("v1.0");
            version.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            //创建第六行  -->请求参数

            XWPFTableRow requesetParam = table.createRow();
            requesetParam.getCell(0).setText("请求参数");
            requesetParam.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));
            List<SysApiParam> params = null;
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("apiId",api.getId());
            params = sysApiParamService.getList(hashMap);
            params.forEach(param ->{
                XWPFTableRow row = table.createRow();
                row.getCell(0).setText("请求类型");
                row.getCell(1).setText(param.getParamType());
                row.getCell(2).setText("请求名称");
                row.getCell(3).setText(param.getParamName());
                row.getCell(4).setText("参数说明");
                row.getCell(5).setText(param.getNote());
                row.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(500));
            });

            //返回结果
            XWPFTableRow resultCell = table.createRow();
            resultCell.getCell(0).setText("返回结果");
            resultCell.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(400));

//            List<SysApiResult> results = sysApiResultService.getList(hashMap);
            QueryWrapper queryWrapper = getQueryWrapper(SysApiResult.class);
            List<SysApiResult> results = sysApiResultService.query(queryWrapper.eq("apiId",api.getId()).orderBy("id","desc"));
            results.forEach(result->{
                XWPFTableRow row = table.createRow();
                row.getCell(0).setText("返回类型");
                row.getCell(1).setText(result.getParamType());
                XWPFTableCell cell = row.getCell(2);
                cell.setText("返回名称");
                row.getCell(3).setText(result.getParamName());
                row.getCell(4).setText("返回说明");
                row.getCell(5).setText(result.getNote());
                row.getCtRow().addNewTrPr().addNewTrHeight().setVal(BigInteger.valueOf(500));
            });

            //创建第六行 -->
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setBold(true);
//            run.setColor("FF0000");

            run.setText("-------------------------------------------------------------------------------");
//            fillTable(table);
            mergeCellsHorizontal(table,0,1,5);
            mergeCellsHorizontal(table,1,1,5);
            mergeCellsHorizontal(table,2,1,5);
            mergeCellsHorizontal(table,3,1,5);
            mergeCellsHorizontal(table,4,1,5);
            mergeCellsHorizontal(table,5,1,5);
        }
        return document;
    }

    private void setTableStyle(XWPFTable table) {
        //表格属性
//        CTTblPr tblPr = table.getCTTbl().addNewTblPr();
//        tblPr.getTblW().setType(STTblWidth.DXA);
//        tblPr.getTblW().setW(new BigInteger("7000"));
//        CTTblWidth width = tblPr.addNewTblW();
//
//        width.setW(BigInteger.valueOf(5000));
//        //设置表格宽度为非自动
//        width.setType(STTblWidth.DXA);

        //设置边距
        CTTblBorders borders =table.getCTTbl().getTblPr().addNewTblBorders();
        CTBorder hBorder = borders.addNewInsideH();
//        hBorder.setVal(STBorder.Enum.forString("dashed"));
        hBorder.setSz(new BigInteger("2"));
//        hBorder.setColor("0000FF");

        CTBorder vBorder=borders.addNewInsideV();
//        vBorder.setVal(STBorder.Enum.forString("dotted"));
        vBorder.setSz(new BigInteger("2"));
//        vBorder.setColor("00FF00");
        CTBorder lBorder=borders.addNewLeft();
//        lBorder.setVal(STBorder.Enum.forString("double"));
        lBorder.setSz(new BigInteger("2"));
//        lBorder.setColor("3399FF");

        CTBorder rBorder=borders.addNewRight();
//        rBorder.setVal(STBorder.Enum.forString("single"));
        rBorder.setSz(new BigInteger("2"));
//        rBorder.setColor("F2B11F");

        CTBorder tBorder=borders.addNewTop();
//        tBorder.setVal(STBorder.Enum.forString("thick"));
        tBorder.setSz(new BigInteger("2"));
//        tBorder.setColor("C3599D");

        CTBorder bBorder=borders.addNewBottom();
//        bBorder.setVal(STBorder.Enum.forString("wave"));
        bBorder.setSz(new BigInteger("2"));
//        bBorder.setColor("BF6BCC");
    }
    /***
     * 导出word 设置行宽
     * @param table
     * @param width
     */
    private  void setTableWidth(XWPFTable table,String width){
        CTTbl ttbl = table.getCTTbl();
        CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        CTJc cTJc=tblPr.addNewJc();
        cTJc.setVal(STJc.Enum.forString("center"));
        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);
    }


    /***
     * 合并列
     * @param table
     * @param row 当前行下标
     * @param fromCell  起始列
     * @param toCell   终止列
     */
    private  void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if ( cellIndex == fromCell ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
    public  void fillTable(XWPFTable table) {
        for (int rowIndex = 0; rowIndex < table.getNumberOfRows(); rowIndex++) {
            XWPFTableRow row = table.getRow(rowIndex);
            row.setHeight(380);
            for (int colIndex = 0; colIndex < row.getTableCells().size(); colIndex++) {
                XWPFTableCell cell = row.getCell(colIndex);
                if(rowIndex%2==0){
                    setCellText(cell, " cell " + rowIndex + colIndex + " ", "D4DBED", 1000);
                }else{
                    setCellText(cell, " cell " + rowIndex + colIndex + " ", "AEDE72", 1000);
                }
            }
        }
    }

    public  void setCellText(XWPFTableCell cell,String text, String bgcolor, int width) {
        CTTc cttc = cell.getCTTc();
        CTTcPr cellPr = cttc.addNewTcPr();
        cellPr.addNewTcW().setW(BigInteger.valueOf(width));
        //cell.setColor(bgcolor);
        CTTcPr ctPr = cttc.addNewTcPr();
        CTShd ctshd = ctPr.addNewShd();
        ctshd.setFill(bgcolor);
        ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
        cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
        cell.setText(text);
    }
}
